package org.yunai.swjg.server.module.quest;

import org.jumpmind.symmetric.csv.CsvReader;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import org.yunai.swjg.server.core.service.Online;
import org.yunai.swjg.server.module.currency.Currency;
import org.yunai.swjg.server.module.inventory.ItemParam;
import org.yunai.swjg.server.module.quest.condition.IQuestCondition;
import org.yunai.swjg.server.module.quest.condition.QuestConditionFactory;
import org.yunai.swjg.server.module.quest.template.QuestTemplate;
import org.yunai.yfserver.common.LoggerFactory;
import org.yunai.yfserver.util.CsvUtil;
import org.yunai.yfserver.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;

/**
 * 任务Service
 * User: yunai
 * Date: 13-5-8
 * Time: 下午11:42
 */
@Service
public class QuestService {

    private static final Logger LOGGER_GAME = LoggerFactory.getLogger(LoggerFactory.Logger.game, QuestService.class);

    private Map<Integer, AbstractQuest> quests;

    @PostConstruct
    public void init() {
        LOGGER_GAME.info("[init] [load quest.csv begin].");
        loadQuestTemplate();
        LOGGER_GAME.info("[init] [load quest.csv success].");
    }

    private void loadQuestTemplate() {
        CsvReader reader = null;
        // 任务模版
        Map<Integer, QuestTemplate> templates = new HashMap<>();
        try {
            reader = CsvUtil.createReader("csv/quest/quest_template.csv");
            reader.readHeaders();
            while (reader.readRecord()) {
                QuestTemplate template = genQuestTemplate(reader);
                templates.put(template.getId(), template);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        // 生成quests
        quests = new HashMap<>(templates.size());
        for (QuestTemplate template : templates.values()) {
            quests.put(template.getId(), AbstractQuest.Factory.create(template));
        }
        // 拼接前置/后置quest
        for (AbstractQuest quest : quests.values()) {
            Integer[] preQuestIds = StringUtils.splitInt(quest.getTemplate().getPreQuests(), "\\|");
            for (Integer preQuestId : preQuestIds) {
                AbstractQuest preQuest = quests.get(preQuestId);
                quest.addPreQuest(preQuest);
                preQuest.addNextQuest(quest);
            }
        }
    }

    @SuppressWarnings("unchecked")
    private QuestTemplate genQuestTemplate(CsvReader reader) throws IOException {
        QuestTemplate template = new QuestTemplate();
        template.setId(CsvUtil.getInt(reader, "id", -1));
        template.setTitle(CsvUtil.getString(reader, "title", ""));
        template.setType(QuestDef.Type.valueOf(CsvUtil.getInt(reader, "type", 0)));
        template.setAcceptMinLevel(CsvUtil.getShort(reader, "acceptMinLevel", (short) -1));
        template.setContent(CsvUtil.getString(reader, "content", ""));
        template.setRegion(CsvUtil.getInt(reader, "region", 0));
        template.setAcceptNPC(CsvUtil.getInt(reader, "acceptNPC", 0));
        template.setFinishNPC(CsvUtil.getInt(reader, "finishNPC", 0));
        template.setPreQuests(CsvUtil.getString(reader, "preQuests", ""));
        // 完成任务条件
        String[] finishConditions = StringUtils.split(CsvUtil.getString(reader, "finishConditions", ""), ";");
        List<IQuestCondition> finishConditionList = finishConditions.length > 0 ? new ArrayList<>(finishConditions.length)
                : Collections.EMPTY_LIST;
        for (String finishCondition : finishConditions) {
            finishConditionList.add(QuestConditionFactory.create(finishCondition));
        }
        template.setFinishConditions(finishConditionList);
        template.setBonusCurrency(Currency.valueOf(CsvUtil.getInt(reader, "bonusCurrency", 0)));
        template.setBonusCurrencyNum(CsvUtil.getInt(reader, "bonusCurrencyNum", 0));
        template.setBonusExp(CsvUtil.getInt(reader, "bonusExp", 0));
        // 完成任务道具奖励
        String[] bonusItems = StringUtils.split(CsvUtil.getString(reader, "bonusItems", ""), ";");
        List<ItemParam> bonusItemList = bonusItems.length > 0 ? new ArrayList<>(bonusItems.length) : Collections.EMPTY_LIST;
        for (String bonusItem : bonusItems) {
            Integer[] bonusItemParam = StringUtils.splitInt(bonusItem, "\\|");
            bonusItemList.add(new ItemParam(bonusItemParam[0], bonusItemParam[1]));
        }
        template.setBonusItems(bonusItemList);
        return template;
    }

    /**
     * @param questId 任务编号
     * @return 任务逻辑对象
     */
    public AbstractQuest getQuest(Integer questId) {
        return quests.get(questId);
    }

    /**
     * @return 所有任务逻辑对象
     */
    public Collection<AbstractQuest> getAllQuest() {
        return quests.values();
    }

    /**
     * 接受任务
     *
     * @param online 在线信息
     * @param questId 任务编号
     */
    public void accept(Online online, Integer questId) {
        AbstractQuest quest = quests.get(questId);
        if (quest == null) {
            return;
        }
        quest.accept(online);
    }

    /**
     * 取消任务
     *
     * @param online 在线信息
     * @param questId 任务编号
     */
    public void cancel(Online online, Integer questId) {
        AbstractQuest quest = quests.get(questId);
        if (quest == null) {
            return;
        }
        quest.cancel(online);
    }

    /**
     * 完成任务
     *
     * @param online 在线信息
     * @param questId 任务编号
     */
    public void finish(Online online, Integer questId) {
        AbstractQuest quest = quests.get(questId);
        if (quest == null) {
            return;
        }
        quest.finish(online);
    }
}
